# -*- coding:utf-8 -*-
import os
from tempfile import TemporaryDirectory

from src.utils import runcmd
from src.core.global_config import GlobalConfig
from src.core.oetype import ArchType
from src.utils.logger import logger


class ReplaceRPMS(object):
    _rpms_path = None
    _work_dir = None
    _product_name = None
    _version_id = None
    _version_info = None

    def __init__(self, rpms_path, work_dir, product_name, version_id, version_info):
        self._rpms_path = rpms_path
        self._work_dir = work_dir
        self._product_name = product_name
        self._version_id = version_id
        self._version_info = version_info
        self._origin_version_info = GlobalConfig.BASE_ISO_VERSION

    def replace_in_repo(self):
        for root, dirs, files in os.walk(self._rpms_path):
            for f in files:
                src_file = os.path.join(root, f)
                dst_file = os.path.join(os.path.join(self._work_dir, "Packages"), f)
                runcmd.cp_file(src_file, dst_file)

    def replace_in_bootimg(self):
        efiboog_mount_path = os.path.join("/var/tmp", "efiboot_")
        efiboot = self._work_dir + "/images/efiboot.img"
        with TemporaryDirectory(prefix=efiboog_mount_path, dir="/var/tmp") as iso_dir:
            ret = runcmd.mount(efiboot, iso_dir, "vfat", "rw")
            if ret:
                logger.error("Failed to mount %s to %s", efiboot, iso_dir)
                return ret
            logger.info("efiboog.img mounted on dir: %s", iso_dir)
            runcmd.replace(iso_dir + "/EFI/BOOT/grub.cfg", "openEuler", self._product_name)
            runcmd.replace(iso_dir + "/EFI/BOOT/grub.cfg", self._origin_version_info, self._version_info)
            logger.info("modify efiboot.img files successfully!")
            ret = runcmd.umount(iso_dir)
            if ret:
                logger.error("Failed to umount dior %s", iso_dir)
                return ret
        return ret

    def replace_in_minios(self):
        # unsquashfs
        install_img_path = self._work_dir + "/images/install.img"
        runcmd.unsquashfs(install_img_path, self._work_dir + "/images/squashfs-root")
        # mount
        install_mount_path = os.path.join("/var/tmp", "install_")
        squashfs_path = self._work_dir + "/images/squashfs-root"
        rootfs_path = squashfs_path + "/LiveOS/rootfs.img"
        with TemporaryDirectory(prefix=install_mount_path, dir="/var/tmp") as install_dir:
            ret = runcmd.mount(rootfs_path, install_dir, "ext4", "rw")
            if ret:
                logger.error("Failed to mount %s to %s", rootfs_path, install_dir)
                return ret
            logger.info("install.img mounted on dir %s", install_dir)
            # openEuler-release %config(noreplace) /etc/os-release
            runcmd.remove_file(install_dir + "/etc/os-release")
            runcmd.remove_file(install_dir + "/etc/anaconda.repos.d/openEuler.repo")
            build_stamp_file = runcmd.read_file(install_dir + "/.buildstamp").split("\n")
            for line in build_stamp_file:
                if line.startswith("Version="):
                    self._origin_version_info = line.split("Version=")[-1]
            runcmd.replace(install_dir + "/.buildstamp", "Product=openEuler", "Product={}".format(self._product_name))
            runcmd.replace(install_dir + "/.buildstamp", "Version=" + self._origin_version_info, "Version={}".format(self._version_info))

            runcmd.replace(install_dir + "/usr/lib/python3.7/site-packages/productmd/treeinfo.py",
                           "            self.short = None",
                           "            self.short = \"\"")
            runcmd.replace(install_dir + "/etc/anaconda/product.d/openeuler.conf",
                           "product_name = openEuler",
                           "product_name = {}".format(self._product_name))
            runcmd.replace(install_dir + "/etc/anaconda/product.d/openeuler.conf",
                           "openEuler-release", self._product_name + "-release")
            src_eula_file = install_dir + "/usr/share/openEuler-release/EULA"
            dst_eula_file = install_dir + "/usr/share/{}-release/EULA".format(self._product_name)
            dst_eula_dirname = os.path.dirname(dst_eula_file)
            if os.path.exists(dst_eula_dirname) is False:
                os.makedirs(dst_eula_dirname)
            runcmd.cp_file(src_eula_file, dst_eula_file)
            runcmd.remove_file(src_eula_file)
            # replace rpm
            for root, dirs, files in os.walk(self._rpms_path):
                for f in files:
                    src_file = os.path.join(root, f)
                    runcmd.rpm_setup(src_file, install_dir)
        # umount + squashfs
            runcmd.umount(install_dir)
            runcmd.mksquashfs(squashfs_path, install_img_path)
        # delete
        runcmd.remove_file(squashfs_path)

    def replace_in_iso(self):
        if GlobalConfig.ARCH == ArchType.X86_64:
            # isolinux
            runcmd.replace(self._work_dir + "/isolinux/grub.conf", "openEuler", self._product_name)
            runcmd.replace(self._work_dir + "/isolinux/grub.conf", self._origin_version_info, self._version_info)

            runcmd.replace(self._work_dir + "/isolinux/isolinux.cfg", "openEuler", self._product_name)
            runcmd.replace(self._work_dir + "/isolinux/isolinux.cfg", self._origin_version_info, self._version_info)

        # UEFI
        runcmd.replace(self._work_dir + "/EFI/BOOT/grub.cfg", "openEuler", self._product_name)
        runcmd.replace(self._work_dir + "/EFI/BOOT/grub.cfg", self._origin_version_info, self._version_info)

        # treeinfo
        treeinfo = self._work_dir + "/.treeinfo"
        runcmd.replace(treeinfo,
                       "family = openEuler",
                       "family = {}".format(self._product_name))
        runcmd.replace(treeinfo,
                       "version = " + self._origin_version_info,
                       "version = {}".format(self._version_info))
        runcmd.replace(treeinfo,
                       "name = openEuler-" + self._origin_version_info,
                       "name = {}-{}".format(self._product_name, self._version_info))

    def replace_normal_xml(self):
        normal_xml = self._work_dir + "/repodata/normal.xml"
        runcmd.replace(normal_xml, "openEuler-release", self._product_name + "-release")
        runcmd.replace(normal_xml, "openEuler-performance", self._product_name + "-performance")
        runcmd.replace(normal_xml, "openEuler-latest-release", self._product_name + "-latest-release")

    def replace_rpms(self):
        self.replace_in_minios()
        self.replace_in_iso()
        self.replace_in_bootimg()
        self.replace_in_repo()
        self.replace_normal_xml()
